#include "strlist.h"
#include "zkemsdk.h"
#include "udk.h"
#include "standalonecuber.h"
#include "commpro.h"
#include "protocmd.h"

static void readCallBack(void* cookie, int DataType, int nDataSize, char* DataBuffer)
{
  //FIXME
}
CStandaloneCuber::CStandaloneCuber(){
}
CStandaloneCuber::~CStandaloneCuber(){
}
UDK_HANDLE 
CStandaloneCuber::Connect(const char* parameters){
  UDK_HANDLE h=NULL;
  PStrList params=slCreate("=");
  char* prot=NULL;
  char* address=NULL;
  char* password=NULL;
  int port,speed;
  int commkey=0;
  if(!parameters) goto Connect_ERROR;
  slSetText(params, parameters, ",");
  //pass all necessary params  
  prot = slGetValue(params, "protocol");
  if(!prot) slGetValue(params, "Protocol");
  if(!prot) slGetValue(params, "prot");
  if(!prot) slGetValue(params, "Prot");
  if(!prot) slGetValue(params, "Protocol");
  if(!prot) goto Connect_ERROR;
  
  address=slGetValue(params, "address");
  if(!address) address=slGetValue(params, "Address");
  if(!address) address=slGetValue(params, "Addr");
  if(!address) address=slGetValue(params, "addr");
  if(!address) address=slGetValue(params, "IPAddress");
  if(!address) address=slGetValue(params, "ipaddress");
  if(!address) address=slGetValue(params, "UID");
  if(!address) address=slGetValue(params, "uid");
  if(!address) goto Connect_ERROR;
  port=slGetValueInt(params, "port",0);
  if(!port) slGetValueInt(params, "Port",0);
  speed=slGetValueInt(params, "Speed",0);
  if(!speed) slGetValueInt(params, "speed",0);
  password = slGetValue(params, "passwd");
  if(!password) password = slGetValue(params, "password");
  if(!password) password = slGetValue(params, "PASSWORD");  

  if(password){
	  commkey=strtoul(password,NULL,0);
  }
  	  
  if(!strcmp(prot,"TCP")){
	  h = Z_Connect_NETEX(address,port,(void*)readCallBack,NULL,commkey);	  	  
  }else if(!strcmp(prot,"UDP")){
	  h = Z_Connect_NET(address,port,(void*)readCallBack,NULL,commkey);
  }else if(!strcmp(prot,"P4P")){
	  h = Z_Connect_P4P(address,(void*)readCallBack,NULL,commkey);
  }
Connect_ERROR:
  slFree(params);
  return h;
}
void 
CStandaloneCuber::Disconnect(UDK_HANDLE h){
  Z_Close(h);
}

struct StdPullErrnoMap {
    int std_errno;
    int pull_errno;
} errno_map[] = {
    {ZKEMSDK_ERR_AUTH, ERR_CMD_COMKEY_ERROR},
    {ZKEMSDK_ERR_INIT, ERR_INIT},
    {ZKEMSDK_ERR_TIMEOUT, ERR_CONNECT_TIMEOUT},
};

int CStandaloneCuber::GetLastError()
{
    int ret, i = 0, lasterror = 0;

    ret = Z_LastError();
    for (i = 0; i < sizeof (errno_map) / sizeof(struct StdPullErrnoMap); i++)
    {
        if (ret == errno_map[i].std_errno) {
            lasterror = errno_map[i].pull_errno;
            break;
        }
    }
    if (!lasterror) 
        lasterror = ret;
    return lasterror;
}

int CStandaloneCuber::SearchDevices(char *CommType,char *Address, char *Buffer,int *BufferLength)
{
  return Z_SearchDevice(CommType,Address,Buffer,BufferLength);
}
int CStandaloneCuber::GetLockCount(UDK_HANDLE h)
{
    //it seems stdsdk does not support this,just return 1;
    return 1;
}
int CStandaloneCuber::SetLockState(UDK_HANDLE h,int lock_no,int opentime)
{
  int opencount=0;
  //stdsdk does not support lock number? just ignore it
  //Z_Unlock request opentime as 100ms unit
  if(opentime>=255)
    opencount=255;
  else if((opentime>=1)&&(opentime<=8))
    opencount=opentime*30;
  else if(opentime>8)
    opencount=8*30;
  return Z_Unlock(h,opencount);
}
int CStandaloneCuber::GetLockState(UDK_HANDLE h,int lock_no)
{
  int ret;
  int lockstate=0;
  //suppress compiler warning
  if(lock_no) {}
  ret = Z_GetDoorState(h,&lockstate);
  if(ret==Z_ERROR_OK) {
    UDK_LOGD("Z_ERROR_OK returned");
	ret = UDK_LOCK_STATE_LOCK_ON;
	//translate stdstk state to udk
	if(0==lockstate)
	  ret=UDK_LOCK_STATE_LOCK_OFF;
	//there is no 0 state ??
   }
  return ret;
}

int CStandaloneCuber::GetComPwd(UDK_HANDLE h, char *buffer, int *BufferLen)
{
    int ret = 0, Pin = 0;
    char item[7];
    
    strcpy(item, "COMKey");
    ret = Z_GetSysOption(h, item, buffer);
    if (ret == Z_ERROR_OK) {
        *BufferLen = strlen(buffer);
        return 0;
    } else {
        return ret;
    }
}


int CStandaloneCuber::MobileAtt(UDK_HANDLE h, int operate, char *premeters, char *Buffer,int* BufferLength)
{
	return Z_MobileAtt(h, operate, premeters, Buffer, BufferLength);
}

int CStandaloneCuber::GetDeviceParam(UDK_HANDLE h, char *Buffer, int Bufferlen, char *Item)
{
	char value[256] = {0x0};
	int ret = 0;
	ret = Z_GetSysOption(h, Item, value);
	if(ret == Z_ERROR_OK)
	{
		sprintf(Buffer, "%s=%s", Item, value);
	}
	return ret;
}

int CStandaloneCuber::SetDeviceParam(UDK_HANDLE h, char *ItemandValues)
{
	int ret =0;
	char *p = strchr(ItemandValues, '=');
	if (NULL == p)
	{
		return Z_ERROR_PARAM;
	}
	*p = '\0';
	//sscanf(ItemandValues, "%s=%s", item, value);
	//UDK_LOGD("SetDeviceParam item=%s, value=%s\n", item, value);
	//if (strlen(item) == 0) return Z_ERROR_PARAM;
	ret = Z_SetSysOption(h, ItemandValues, ++p);
	return ret;
}

int CStandaloneCuber::SetDownloadProcessCallBack(UDK_HANDLE h, void *pCallBackFun)
{
	return Z_SetDownloadProcessCallBack(h, pCallBackFun);
}

int CStandaloneCuber::ResetDeviceExt(UDK_HANDLE h, char *parameters)
{
	return Z_ReSetDeviceExt(h, parameters);
}





